#include <cppunit/config/SourcePrefix.h>

#include "TestConstraintTable.h"
#include <iostream>
#include <string>

void ConstraintTableTest::setUp()
{
	std::cout << "Test ConstraintTable setUp()\n";
}

void ConstraintTableTest::tearDown()
{
}

// Registers the fixture into the 'registry'
CPPUNIT_TEST_SUITE_REGISTRATION( ConstraintTableTest ); // Note 4 

void ConstraintTableTest::testConstructor() {
	ConstraintTable table = ConstraintTable();
}

void ConstraintTableTest::testGetNumberOfEntry() {
	ConstraintTable table = ConstraintTable();
	CPPUNIT_ASSERT( table.getNumberOfEntries() == 0);
	table.addConstraintEntry(WITH_INTEGER, "15", INTEGER, NONE , "c", SYNONYM_CONSTANT, VALUE);
	CPPUNIT_ASSERT( table.getNumberOfEntries() == 1);
	table.addConstraintEntry(WITH_INTEGER, "15", INTEGER, NONE , "c", SYNONYM_CONSTANT, VALUE);
	CPPUNIT_ASSERT( table.getNumberOfEntries() == 2);
	table.addConstraintEntry(WITH_INTEGER, "15", INTEGER, NONE , "c", SYNONYM_CONSTANT, VALUE);
	CPPUNIT_ASSERT( table.getNumberOfEntries() == 3);

}

void ConstraintTableTest::testAdd() {

	ConstraintTable table = ConstraintTable();

	// INTEGER type of with clause
	// 15 = c.value
	CPPUNIT_ASSERT( table.addConstraintEntry(WITH_INTEGER, "15", INTEGER, NONE , "c", SYNONYM_CONSTANT, VALUE) == true);

	// c.value = 15
	CPPUNIT_ASSERT( table.addConstraintEntry(WITH_INTEGER, "c", SYNONYM_CONSTANT, VALUE, "15", INTEGER, NONE) == true);

	// c.value = a.stmt#
	CPPUNIT_ASSERT( table.addConstraintEntry(WITH_INTEGER, "c", SYNONYM_VARIABLE, VALUE, "a", SYNONYM_ASSIGN, STMT_INDEX) == true);

	// c = c2
	CPPUNIT_ASSERT( table.addConstraintEntry(WITH_INTEGER, "c", SYNONYM_CONSTANT, NONE, "c2", SYNONYM_CONSTANT, NONE) == true);

	// c = 15
	CPPUNIT_ASSERT( table.addConstraintEntry(WITH_INTEGER, "c", SYNONYM_CONSTANT, NONE, "15", INTEGER, NONE) == true);

	// String type of with clause
	// p.procName = "abc"
	CPPUNIT_ASSERT( table.addConstraintEntry(WITH_STRING, "p", SYNONYM_PROCEDURE, PROC_NAME, "abc", STRING, NONE) == true);

	// p.procName = p2.procName
	CPPUNIT_ASSERT( table.addConstraintEntry(WITH_STRING, "p", SYNONYM_PROCEDURE, PROC_NAME, "p2", SYNONYM_PROCEDURE, PROC_NAME) == true);

	// v.varName = "Jolly"
	CPPUNIT_ASSERT( table.addConstraintEntry(WITH_STRING, "v", SYNONYM_VARIABLE, VAR_NAME, "Jolly", STRING, NONE) == true);

}

void ConstraintTableTest::testGetEntry() {
	ConstraintTable table = ConstraintTable();

	table.addConstraintEntry(WITH_STRING, "v", SYNONYM_VARIABLE, VAR_NAME, "Jolly", STRING, NONE);
	table.addConstraintEntry(WITH_STRING, "p", SYNONYM_PROCEDURE, PROC_NAME, "p2", SYNONYM_PROCEDURE, PROC_NAME);
	table.addConstraintEntry(WITH_INTEGER, "c", SYNONYM_CONSTANT, NONE, "15", INTEGER, NONE);

	ConstraintEntry entry = table.getConstraintEntry(1);
	CPPUNIT_ASSERT( entry.constraintType == WITH_STRING);
	CPPUNIT_ASSERT( entry.constraintArguments[0] == "p");
	CPPUNIT_ASSERT( entry.constraintArguments[1] == "p2");
	CPPUNIT_ASSERT( entry.constraintArgumentTypes[0] == SYNONYM_PROCEDURE);
	CPPUNIT_ASSERT( entry.constraintArgumentTypes[1] == SYNONYM_PROCEDURE);
	CPPUNIT_ASSERT( entry.constraintAttrTypes[0] == PROC_NAME);
	CPPUNIT_ASSERT( entry.constraintAttrTypes[1] == PROC_NAME);

	entry = table.getConstraintEntry(2);
	CPPUNIT_ASSERT( entry.constraintType == WITH_INTEGER);
	CPPUNIT_ASSERT( entry.constraintArguments[0] == "c");
	CPPUNIT_ASSERT( entry.constraintArguments[1] == "15");
	CPPUNIT_ASSERT( entry.constraintArgumentTypes[0] == SYNONYM_CONSTANT);
	CPPUNIT_ASSERT( entry.constraintArgumentTypes[1] == INTEGER);
	CPPUNIT_ASSERT( entry.constraintAttrTypes[0] == NONE);
	CPPUNIT_ASSERT( entry.constraintAttrTypes[1] == NONE);

}
